package lines.gameengine.tracer;

import lines.gameengine.FieldPoint;

/**
 * Helper for iteration around the given center by peers.
 * @author vpotapenko
 */
public class FieldPeerLocator {

    private static final FieldPoint[] locatorPatterns = new FieldPoint[4];
    static {
        locatorPatterns[0] = new FieldPoint(-1, 0);
        locatorPatterns[1] = new FieldPoint(0, -1);
        locatorPatterns[2] = new FieldPoint(1, 0);
        locatorPatterns[3] = new FieldPoint(0, 1); 
    }

    private final int width;
    private final int height;

    private FieldPoint center;

    private int currentPosition = -1;

    /**
     * Construct the iterator with width and height of field
     * @param width width of field
     * @param height height of field
     */
    public FieldPeerLocator(int width, int height) {
        this.width = width;
        this.height = height;
    }

    /**
     * Initialized center point
     * @param center
     */
    public void init(FieldPoint center) {
        this.center = center;

        currentPosition = -1;
        findNext();
    }

    /**
     * Returns <code>true</code> if locator has a next peer of the center
     * @return <code>true</code> if locator has a next peer of the center
     */
    public boolean hasNext() {
        return currentPosition >= 0;
    }

    /**
     * Returns a next peer point and find a next peer
     * @return a next peer point
     */
    public FieldPoint next() {
        if (currentPosition < 0) return null;

        FieldPoint patternPoint = locatorPatterns[currentPosition];
        FieldPoint next = new FieldPoint(center.getX() + patternPoint.getX(),
                                         center.getY() + patternPoint.getY());
        findNext();
        return next;
    }

    private void findNext() {
        currentPosition++;
        if (currentPosition >= locatorPatterns.length) {
            currentPosition = -1;
            return;
        }

        FieldPoint patternPoint = locatorPatterns[currentPosition];
        int x = center.getX() + patternPoint.getX();
        if (!isValidX(x)) {
            findNext();
            return;
        }

        int y = center.getY() + patternPoint.getY();
        if (!isValidY(y)) findNext();
    }

    private boolean isValidY(int y) {
        return y >=0 && y < height;
    }

    private boolean isValidX(int x) {
        return x >=0 && x < width;
    }
}
